﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DimensionData.Data2
{
    /// <summary>
    /// 组合之后的维度表
    /// </summary>
    public class DCTable
    {
        public List<DTable> Tables { get; private set; }
        public DRelationChain RelationChain { get; set; }

        internal DCTable()
        {
            Tables = new List<DTable>();
            RelationChain = new DRelationChain();
        }

        /// <summary>
        /// 组合其它的维度表
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public DCTable Combine(DTable table)
        {
            this.Tables.Add(table);
            this.RelationChain.Append(new Relations.DDRelation(this.Tables.Last(), table));
            return this;
        }

        /// <summary>
        /// 计算维度树
        /// </summary>
        /// <returns></returns>
        public DTree CalcDTree(DContext context)
        {
            DTable firstTable = Tables[0];
            DRelation firstRelation = this.RelationChain.First();

            DData data = firstTable.GetData(context);
            DTree tree = data.ConvertToTree();
            tree.Table = this;

            Stack<DTreeNode> stack = new Stack<DTreeNode>();
            foreach (var node in tree.Nodes)
            {
                stack.Push(node);
            }

            if (firstRelation != null)
            {
                while (stack.Count > 0)
                {
                    DTreeNode node = stack.Pop();
                    node.NextTree = firstRelation.GetTree(context, node);

                    foreach (var subNode in node.Nodes)
                    {
                        stack.Push(subNode);
                    }
                }
            }
            else
            {
                while (stack.Count > 0)
                {
                    DTreeNode node = stack.Pop();
                    foreach (var subNode in node.Nodes)
                    {
                        stack.Push(subNode);
                    }
                }
            }

            return tree;
        }
    }
}
